<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>洋铲工作室CDN</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        font-size: 12px;
        color: #333;
        font-family: "微软雅黑";
      }

      p.file-path {
        height: 38px;
        display: flex;
        align-items: center;
        padding: 0 16px;
        font-weight: bold;
        color: #000;
      }

      .file-table {
        height: calc(100vh - 40px);
        overflow: hidden;
        width: calc(100vw - 2px);
        border: 1px solid #d7d7d7;
        display: flex;
        flex-direction: column;
      }

      .file-table-header {
        display: flex;
        align-items: center;
        justify-content: space-around;
        height: 38px;
        column-gap: 1px;
        background: #d7d7d7;
        border-bottom: 1px solid #d7d7d7;
        flex-shrink: 0;
      }

      .file-table-header > div {
        font-size: 14px;
        font-weight: bold;
        flex-grow: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100%;
        background: #f4f4f4;
      }

      .file-table-content {
        flex-grow: 1;
        display: flex;
        align-items: center;
        height: 38px;
        background: #fff;
        flex-direction: column;
        row-gap: 2px;
        overflow: auto;
      }

      .file-table-row {
        width: 100%;
        display: flex;
        justify-content: space-around;
        background-color: #d7d7d7;
        height: 38px;
        column-gap: 3px;
        flex-shrink: 0;
        cursor: pointer;
      }

      .file-table-row:hover > .file-table-cell {
        background-color: #f4f4f4;
      }

      .file-table-cell {
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 25%;
        margin: -1px;
        background-color: #fff;
        overflow: hidden;
      }
      a {
        color: #0172ff;
        font-size: 14px;
        cursor: pointer;
      }
      a:hover {
        opacity: 0.5;
      }
      .file-type {
        color: #999;
      }
    </style>
    <script>
      const basePath = "http://yangchan.work/cdn";
      let currentPath = "";
      let lastPath = "";

      const numToStr = (num) =>
        String(num).length === 1 ? `0${num}` : String(num);

      function parseDate(dateString) {
        const parts = dateString.split(" ");
        const dateParts = parts[0].split("-");
        const timeParts = parts[1].split(":");

        const day = parseInt(dateParts[0], 10);
        const monthNames = [
          "Jan",
          "Feb",
          "Mar",
          "Apr",
          "May",
          "Jun",
          "Jul",
          "Aug",
          "Sep",
          "Oct",
          "Nov",
          "Dec",
        ];
        const monthIndex = monthNames.indexOf(dateParts[1]);
        const year = parseInt(dateParts[2], 10);
        const hours = parseInt(timeParts[0], 10);
        const minutes = parseInt(timeParts[1], 10);
        const date = new Date(year, monthIndex, day, hours, minutes);

        const _month = numToStr(date.getMonth() + 1);
        const _date = numToStr(date.getDate());
        const _hours = numToStr(date.getHours());
        const _minutes = numToStr(date.getMinutes());

        return `${date.getFullYear()}-${_month}-${_date} ${_hours}:${_minutes}`;
      }

      const bindEvent = () => {
        const tableContentDom = document.querySelector("#table-content");
        const fileNameDoms = tableContentDom.querySelectorAll(".file-name");
        const copyFilePathDoms =
          tableContentDom.querySelectorAll(".copy-file-path");
        [...fileNameDoms].forEach((item) => {
          item.onclick = () => {
            const name = item.innerText;
            if (name === "../" && currentPath === "/") return;

            if (+item.dataset.children !== 1) {
              window.open(basePath + currentPath + name);
              return;
            }

            if (name === "../") {
              const paths = currentPath.split("/");
              paths.pop();
              paths.pop();
              const path = paths.join("/") || "/";
              refreshTable(path);
            } else {
              refreshTable(currentPath + name);
            }
          };
        });
        [...copyFilePathDoms].forEach((item) => {
          item.onclick = () => {
             const name = item.dataset.fileName;

             copyToClipboard(basePath + currentPath + name);
          }
        });
      };

      const dataToDom = (list = []) => {
        return list
          .map((item) => {
            const nameStr = `<a>${item.name}</a>`;
            return `<div class="file-table-row">
          <div class="file-table-cell file-name" data-children="${
            item.hasChildren ? 1 : 0
          }">${nameStr}</div>
          <div class="file-table-cell file-type">${
            item.name === "../" ? "" : item.hasChildren ? "文件夹" : "文件"
          }</div>
          <div class="file-table-cell">${
            item.name === "../" ? "" : item.date
          }</div>
          <div class="file-table-cell">${
            item.hasChildren ? "" : "<a class='copy-file-path' data-file-name='"+item.name+"'>复制地址</a>"
          }</div>
        </div>`;
          })
          .join("");
      };

      const updateTable = (list = []) => {
        const domStr = dataToDom(list);
        const tableContentDom = document.querySelector("#table-content");
        tableContentDom.innerHTML = domStr;
        bindEvent();
      };

      const copyToClipboard = async (content) => {
        // 复制文本内容方法一
        async function copyContent(content) {
          // 复制结果
          let copyResult = true;
          // 设置想要复制的文本内容
          const text = content || "复制内容为空哦~";
          // 判断是否支持clipboard方式
          if (!!window.navigator.clipboard) {
            // 利用clipboard将文本写入剪贴板（这是一个异步promise）
            await window.navigator.clipboard
              .writeText(text)
              .then((res) => {
                console.log("复制成功");
              })
              .catch((err) => {
                console.log("复制失败--采取第二种复制方案", err);
                // clipboard方式复制失败 则采用document.execCommand()方式进行尝试
                copyResult = copyContent2(text);
              });
          } else {
            // 不支持clipboard方式 则采用document.execCommand()方式
            copyResult = copyContent2(text);
          }
          // 返回复制操作的最终结果
          return copyResult;
        }
        // 复制文本内容方法二
        function copyContent2(text) {
          // 复制结果
          let copyResult = true;
          // 创建一个input元素
          let inputDom = document.createElement("textarea");
          // 设置为只读 防止移动端手机上弹出软键盘
          inputDom.setAttribute("readonly", "readonly");
          // 给input元素赋值
          inputDom.value = text;
          // 将创建的input添加到body
          document.body.appendChild(inputDom);
          // 选中input元素的内容
          inputDom.select();
          // 执行浏览器复制命令
          // 复制命令会将当前选中的内容复制到剪切板中（这里就是创建的input标签中的内容）
          // Input要在正常的编辑状态下原生复制方法才会生效
          const result = document.execCommand("copy");
          // 判断是否复制成功
          if (result) {
            console.log("复制成功");
          } else {
            console.log("复制失败");
            copyResult = false;
          }
          // 复制操作后再将构造的标签 移除
          document.body.removeChild(inputDom);
          // 返回复制操作的最终结果
          return copyResult;
        }

        try {
          await copyContent(content);
          return true;
        } catch (err) {
          return Promise.resolve(false);
        }
      };

      const refreshTable = async (path = "/") => {
        const htmlContent = await fetch(basePath + path, {
          headers: {
            "Access-Control-Allow-Origin": "*",
          },
        }).then((result) => result.text());
        const temDom = document.createElement("div");
        temDom.style.display = "none";
        temDom.innerHTML = htmlContent;
        const dataList = [...temDom.querySelectorAll("tr")].map((item) => {
          const displayName = item.querySelector(".display-name");
          const dateStr = item.querySelector(".last-modified");
          const name = displayName.innerText;
          return {
            name,
            date: parseDate(dateStr.innerText),
            hasChildren: name.endsWith("/"),
          };
        });
        updateTable(dataList);
        currentPath = path;
        document.querySelector(".file-path").innerHTML = `路径：${
          basePath + currentPath
        }`;
      };
      refreshTable();
    </script>
  </head>

  <body>
    <p class="file-path">路径：/</p>
    <div class="file-table">
      <div class="file-table-header">
        <div>文件</div>
        <div>类型</div>
        <div>时间</div>
        <div>操作</div>
      </div>
      <div id="table-content" class="file-table-content"></div>
    </div>
  </body>
</html>
